From: Keir Fraser Date: Thu, 14 May 2009 14:46:43 +0000 (+0100) Subject: cpuidle: Fix possible false judge caused by type casting X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~13925 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https://%22%22/%22http:/www.example.com/cgi/%22https:/%22%22?a=commitdiff_plain;h=520302d743e55423d60ff1fdd5b0decf05105973;p=xen.git cpuidle: Fix possible false judge caused by type casting For timer_deadline == 0 or timer_deadline - now > largest u32 case, the expected_us (in u32 type) may become wrong. Add a tunable option to ease conditional adjustment. Signed-off-by: Wei Gang --- diff --git a/xen/arch/x86/acpi/cpu_idle.c b/xen/arch/x86/acpi/cpu_idle.c index 0685194029..91f839e264 100644 --- a/xen/arch/x86/acpi/cpu_idle.c +++ b/xen/arch/x86/acpi/cpu_idle.c @@ -624,6 +624,7 @@ static int check_cx(struct acpi_processor_power *power, xen_processor_cx_t *cx) } static unsigned int latency_factor = 2; +integer_param("idle_latency_factor", latency_factor); static void set_cx( struct acpi_processor_power *acpi_power, diff --git a/xen/arch/x86/acpi/cpuidle_menu.c b/xen/arch/x86/acpi/cpuidle_menu.c index 683dc3bb16..27ed7f5790 100644 --- a/xen/arch/x86/acpi/cpuidle_menu.c +++ b/xen/arch/x86/acpi/cpuidle_menu.c @@ -45,9 +45,15 @@ struct menu_device static DEFINE_PER_CPU(struct menu_device, menu_devices); -static s_time_t get_sleep_length_ns(void) +static unsigned int get_sleep_length_us(void) { - return per_cpu(timer_deadline, smp_processor_id()) - NOW(); + s_time_t us = (per_cpu(timer_deadline, smp_processor_id()) - NOW()) / 1000; + /* + * while us < 0 or us > (u32)-1, return a large u32, + * choose (unsigned int)-2000 to avoid wrapping while added with exit + * latency because the latency should not larger than 2ms + */ + return (us >> 32) ? (unsigned int)-2000 : (unsigned int)us; } static int menu_select(struct acpi_processor_power *power) @@ -56,7 +62,7 @@ static int menu_select(struct acpi_processor_power *power) int i; /* determine the expected residency time */ - data->expected_us = (u32) get_sleep_length_ns() / 1000; + data->expected_us = get_sleep_length_us(); /* find the deepest idle state that satisfies our constraints */ for ( i = 2; i < power->count; i++ )